package cn.yedong.basic.service.impl;

import cn.yedong.basic.dto.PhoneCodeDto;
import cn.yedong.basic.exception.BusinessException;
import cn.yedong.basic.service.IVerifyCodeService;
import cn.yedong.basic.util.StrUtils;
import cn.yedong.basic.util.VerifyCodeUtils;
import cn.yedong.user.domain.User;
import cn.yedong.user.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    /**
     * 注入Redis
     */
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    /**
     *  获取图形验证码
     */
    @Override
    public String getImageCode(String key) {
        //获取4位随机码
        String code = StrUtils.getComplexRandomString(4);
        //将随机码存入redis
        redisTemplate.opsForValue().set(key,code,3, TimeUnit.MINUTES);
        //将随机码加入验证图片用base64编码并返回
        return VerifyCodeUtils.verifyCode(110,40,code);
    }

    /**
     * 获取手机验证码
     * @param phoneCodeDto
     */
    @Override
    public void sendPhoneCode(PhoneCodeDto phoneCodeDto) {
        //一.校验
        String imageCode = phoneCodeDto.getImageCode();
        String imageCodeKey = phoneCodeDto.getImageCodeKey();
        String phone = phoneCodeDto.getPhone();
        //1.空值校验
        if(StringUtils.isEmpty(imageCode) || StringUtils.isEmpty(imageCodeKey) || StringUtils.isEmpty(phone)){
            throw new BusinessException("信息不能为空！");
        }
        //2.重复注册校验
        User user = userMapper.findByPhone(phone);
        if(user != null){
            throw new BusinessException("不能重复注册！请直接登陆，或者<a href='http://localhost:8080/wjma'>忘记密码</a>！");
        }
        //3.验证码校验
        //redis中图形验证码
        Object obj = redisTemplate.opsForValue().get(imageCodeKey);
        //如果redis中国图形验证码过期：3分钟有效
        if(obj == null){
            throw new BusinessException("图像验证码已过期！");
        }
        //如果输入图形验证码不正确
        if(!imageCode.equalsIgnoreCase(obj.toString())){
            throw new BusinessException("图像验证码输入错误！");
        }
        //二.获取验证码【业务键:电话号码 - 手机验证码:时间戳】
        //查询redis中有没有手机验证码
        Object phoneCodeObj = redisTemplate.opsForValue().get("register:" + phone);
        String phoneCode = null;
        //如果验证码过期
        if(phoneCodeObj == null){
             //设置指定长度验证码
             phoneCode = StrUtils.getRandomString(4);
        }else{
            //没有过期——但在1分钟以内
            if(System.currentTimeMillis() - Long.parseLong(phoneCodeObj.toString().split(":")[1]) < 1000*60){
                throw new BusinessException("亲，网络堵塞，请稍后重试！");
            }else{
                //没有过期——且大于1分钟生——成验证码，发送短信，
                phoneCode = phoneCodeObj.toString().split(":")[0];
            }
        }
        //刷新过期时间:三分钟有效
        redisTemplate.opsForValue().set("register:"+phone,phoneCode+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
        //三.发送验证码
        //SmsUtils.sendSms(phone,"欢迎您注册宠物之家！您的验证码是"+phoneCode+"3分钟有效！");
        System.out.println("欢迎您注册宠物之家！您的验证码是" + phoneCode + "，3分钟有效！");
    }

    /**
     * 发送微信绑定手机验证码
     * @param phoneCodeDto
     */
    @Override
    public void binderWechat(PhoneCodeDto phoneCodeDto) {
        //一.校验
        String phone = phoneCodeDto.getPhone();
        if(phone == null){
            throw new BusinessException("电话不能为空！");
        }
        //二.获取验证码【业务键:电话号码 - 手机验证码:时间戳】
        //查询redis中有没有手机验证码
        Object phoneCodeObj = redisTemplate.opsForValue().get("binder:" + phone);
        String phoneCode = null;
        //如果验证码过期；或第一次请求验证码
        if(phoneCodeObj == null){
            //设置指定长度验证码
            phoneCode = StrUtils.getRandomString(4);
        }else{
            //没有过期——但在1分钟以内
            if(System.currentTimeMillis() - Long.parseLong(phoneCodeObj.toString().split(":")[1]) < 1000*60){
                throw new BusinessException("亲，网络堵塞，请稍后重试！");
            }else{
                //没有过期——且大于1分钟生——成验证码，发送短信，
                phoneCode = phoneCodeObj.toString().split(":")[0];
            }
        }
        //刷新过期时间:三分钟有效
        redisTemplate.opsForValue().set("binder:"+phone,phoneCode+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
        //三.发送验证码
        //SmsUtils.sendSms(phone,"欢迎您注册宠物之家！您的验证码是"+phoneCode+"3分钟有效！");
        System.out.println("欢迎您绑定微信账号！您的验证码是" + phoneCode + "，3分钟有效！");
    }
}
